<script setup lang="ts" name="GoodsSku">
import { GoodsInfo, Spec, SpecValue } from '@/types/goods'
import bwPowerSet from '@/utils/power-set';
const emit = defineEmits<{
  (e: 'changeSku', skuId: string): void
}>()
const prpo = defineProps<{
  goodsInfo: GoodsInfo,
  skuId?: String
}>()
// 选中状态改变
const changSelected = (sepcs: Spec, values: SpecValue) => {
  if (values.disabled) return
  if (values.selected) {
    values.selected = false
  } else {
    sepcs.values.forEach(item => item.selected = false)
    values.selected = true
  }
  updateDisabledStatus()
  // 1. 判断规格是否全部选中
  const selected = getSelectedSpec().filter(item => item)
  if (selected.length === prpo.goodsInfo.specs.length) {
    // 说明全部选中
    // 2. 去pathMap找到对应的skuid
    const key = selected.join('❤️')
    const [skuId] = pathMap[key]
    emit('changeSku', skuId)
  }
}
/*
  路径字典
*/
// const getPathMap = () => {
//   const pathMap: any = {}
//   // 1. 过滤掉库存为0的sku
//   const skus = prpo.goodsInfo.skus.filter(item => item.inventory !== 0)
//   // 2. 遍历有效的sku,获取sku的幂集
//   skus.forEach(item => {
//     const arr = item.specs.map(sub => sub.valueName)
//     // 3. 调用powerSet获取幂集
//     const powerSet = bwPowerSet(arr)
//     // 4. 把这些powerSet合并到一个路径字典中
//     powerSet.forEach(sub => {
//       const key = sub.join('👩🏿')
//       // 5. 判断pathMap中有没有key
//       if (key in pathMap) {
//         // 6. 存在
//         pathMap[key].push(item.id)
//       } else {
//         // 7. 不存在
//         pathMap[key] = [item.id]
//       }
//     })
//   })
//   return pathMap
// }
// console.log(getPathMap());
const getPathMap = () => {
  const pathMap: {
    [key: string]: string[]
  } = {}
  // 过滤掉inventory为0的
  const skus = prpo.goodsInfo.skus.filter(item => item.inventory > 0)
  // console.log(newarr);
  // 只要每一项中的valueName value值
  skus.forEach(item => {
    const arr = item.specs.map(item => item.valueName)
    // console.log(specs);
    // 调用幂集进行转换
    const powerSet = bwPowerSet(arr)
    // console.log(newspecs);
    // 将转换完成的数据合并到路径字典
    powerSet.forEach(sub => {
      const key = sub.join('❤️')
      // console.log(key);
      // 判断是否存在 存在累加 不存在添加
      // 判断pathMap中有没有key
      if (key in pathMap) {
        // 存在
        pathMap[key].push(item.id)
      } else {
        // 不存在
        pathMap[key] = [item.id]
      }
    })
  })
  return pathMap
}
const pathMap = getPathMap()
// 获取选中的值  
const getSelectedSpec = () => {
  const arr: string[] = []
  prpo.goodsInfo.specs.forEach(item => {
    const temp = item.values.find(sub => sub.selected)
    arr.push(temp ? temp.name : '')
  })
  return arr
}
// 更新按钮的禁用状态
const updateDisabledStatus = () => {
  const selectArr = getSelectedSpec() // ['','','日本']
  // 根据路径字典 => 更新所有的按钮specValue的状态
  prpo.goodsInfo.specs.forEach((item, index) => {
    item.values.forEach((sub) => {
      // 让当前这个按钮, specValue.name(黑色) 和 selectArr 进行组合
      // 注意：这边尝试组合, 判断是否禁用时, 需要拷贝一份原数组
      const TempArr = [...selectArr] // 防止覆盖解构 到这里 形成一个缓存
      TempArr[index] = sub.name
      // 得到组合后转成字符串的key  '黑色+日本'
      const key = TempArr.filter(item => item).join('❤️')
      if (key in pathMap) {
        // 当前规格的名字在pathMap存在，不禁用
        sub.disabled = false
      } else {
        // 当前规格在pathMap找不到，禁用
        sub.disabled = true
      }
      // if (sub.name in pathMap) {
      //   // 当前规格的名字在pathMap存在，不禁用
      //   sub.disabled = false
      // } else {
      //   // 当前规格在pathMap找不到，禁用
      //   sub.disabled = true
      // }
    })
  })
}
updateDisabledStatus()
// 初始化时，设置默认选中效果
const initSelectedSpec = () => {
  const sku = prpo.goodsInfo.skus.find(item => item.id === prpo.skuId)
  if (sku) {
    // 如果根据父组件传递的skuId找到了对应的sku,设置默认选中
    prpo.goodsInfo.specs.forEach((item, index) => {
      // 获取到sku中选中的规格
      const value = sku.specs[index].valueName
      // console.log(value);
      // 让value对应的规格选中
      const spec = item.values.find(item => item.name === value)
      spec!.selected = true
    })
  }
}
initSelectedSpec()

</script>
<template>
  <div class="goods-sku">
    <dl v-for="item in goodsInfo.specs" :key="item.id">
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="sub in item.values" :key="sub.name">
          <img @click="changSelected(item, sub)" v-if="sub.picture"
            :class="{ selected: sub.selected, disabled: sub.disabled }" :src="sub.picture" alt="" />
          <span @click="changSelected(item, sub)" v-else :class="{ selected: sub.selected, disabled: sub.disabled }">{{
            sub.name
          }}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;

  &.selected {
    border-color: @xtxColor;
  }

  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}

.goods-sku {
  padding-left: 10px;
  padding-top: 20px;

  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;

    dt {
      width: 50px;
      color: #999;
    }

    dd {
      flex: 1;
      color: #666;

      >img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }

      >span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>

